package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Voice;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.VoiceService;
import com.itheima.vo.VoiceVo;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.BindException;
import java.time.Duration;

@Service
public class VoiceManager {

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private VoiceService voiceService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    // 上传语音
    public void sendVoice(MultipartFile soundFile) throws IOException {

        //1.获取登录用户id
        Long userId = UserHolder.get().getId();

        //2. 语音上传fastsfs
        StorePath storePath = client.uploadFile(soundFile.getInputStream(),
                soundFile.getSize(), FileUtil.extName(soundFile.getOriginalFilename()), null);
        String voiceUrl = webServer.getWebServerUrl() + storePath.getFullPath();

        //3.注入userInfo查询个人信息
        UserInfo userInfo = userInfoService.findByUserId(userId);

        // 从redis中查询数据   得到返回值
        String remainingTimes = stringRedisTemplate.opsForValue().get(StrUtil.format(userInfo.getId()+"RemainingTimes"));

        // 如果返回值是null
        if (remainingTimes == null) {

            // 说明登录用户是第一次发送 语音消息 那么我们就给redis中添加一个数值为9的数据 刷新时间为一天
            stringRedisTemplate.opsForValue().set(StrUtil.format(userInfo.getId()+"RemainingTimes"), "9", Duration.ofDays(1));

            // 如果返回值是0
        } else if (remainingTimes.equals("0")) {

            // 说明用户的使用次数已经用完 直接返回
            throw new BindException("今日次数已用完");

        } else {

            // 说明用户还有使用次数  正常使用 但每使用一次 在redis中的数值就会自减一
            stringRedisTemplate.opsForValue().decrement(userInfo.getId()+"RemainingTimes");

        }

        //4.创建Voice对象并赋值
        Voice voice = new Voice();
        voice.setUserId(userId.intValue());
        voice.setAvatar(userInfo.getAvatar());
        voice.setNickname(userInfo.getNickname());
        voice.setGender(userInfo.getGender());
        voice.setAge(userInfo.getAge());
        voice.setSoundUrl(voiceUrl);

        // 给voice对象的次数设置为redis中的次数
        voice.setRemainingTimes(Integer.parseInt(stringRedisTemplate.opsForValue().get(userInfo.getId()+"RemainingTimes")));

        // 保存到mongo
        voiceService.saveVoice(voice);

    }

    // 接收语音
    public VoiceVo findVoice() {

        // 获取用户id
        Long userId = UserHolder.get().getId();

        // 到表中随机查询一个用户
        Voice voice = voiceService.findVoice(userId);

        UserInfo userInfo1 = userInfoService.findByUserId(userId);

        // 去redis中查询是否有此数据
        String RemainingCount = stringRedisTemplate.opsForValue().get(StrUtil.format(userInfo1.getId()+"RemainingCount"));

        // 判断数据
        if (RemainingCount == null) {

            // 说明登录用户是第一次发送 语音消息 那么我们就给redis中添加一个数值为8的数据 刷新时间为一天
            stringRedisTemplate.opsForValue().set(StrUtil.format(userInfo1.getId()+"RemainingCount"), "9", Duration.ofDays(1));

            // 如果返回值是0
        } else if (RemainingCount.equals("0")) {

            // 说明用户的使用次数已经用完 直接返回null
            return null;
        }

        // 那么说明用户还有使用次数  正常使用 但每使用一次 在redis中的数值就会自减一
        stringRedisTemplate.opsForValue().decrement(userInfo1.getId()+"RemainingCount");

        // 将查询回来的用户封装到Voicevo中
        VoiceVo voiceVo = new VoiceVo();
        // 获得登录用户的id
        UserInfo userInfo = userInfoService.findByUserId(voice.getUserId().longValue());

        // 将用户信息赋值到viocevo中
        BeanUtil.copyProperties(userInfo, voiceVo);

        // 不同的字段单独赋值  这里是语音的地址
        voiceVo.setSoundUrl(voice.getSoundUrl());

        // 从redis中获取到用户剩余的次数
        String remainingCount = stringRedisTemplate.opsForValue().get(userInfo1.getId()+"RemainingCount");

        // 再将获取到的用户剩余的次数 赋值给次数字段
        voiceVo.setRemainingTimes(Integer.parseInt(remainingCount));

        // 最后返回这个vo
        return voiceVo;

    }
}
